package cn.etgps.etgps.view;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import cn.etgps.etgps.R;
import cn.etgps.etgps.utils.AppUtils;
import cn.etgps.etgps.utils.Constant;


/**
 * Provide update and load more
 *
 * @author Nicky
 */
public class AutoListView extends ListView implements OnScrollListener {

    public static final int REFRESH = 0;
    public static final int LOADMORE = 1;
    private static final int SPACE = 64;

    private static final int NONE = 0;
    private static final int PULL = 1;
    private static final int RELEASE = 2;
    private static final int REFRESHING = 3;
    private int state;

    private LayoutInflater inflater;
    private View header;
    private View footer;
    private TextView tip;
    private TextView lastUpdate;
    private ImageView refreshing;

    private TextView loadFull;
    private TextView more;
    private ImageView footerProgress;
    private AnimationDrawable progressAnim;
    private AnimationDrawable refreshingAnim;

    private int startY;

    private int firstVisibleItem;
    private int scrollState;
    private int headerContentInitialHeight;
    private int headerContentHeight;

    private boolean isRecorded;
    private boolean isLoading;
    private boolean loadEnable = true;
    private boolean isLoadFull;
    private int pageSize = Constant.PER_PAGE_ITEM_COUNT;

    private OnRefreshListener onRefreshListener;
    private OnLoadListener onLoadListener;

    private View mKeepScreenHeaderView;

    private int mExtraHeaderCount = 0;

    public AutoListView(Context context) {
        super(context);
        initView(context);
    }

    public AutoListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setOverScrollMode(View.OVER_SCROLL_NEVER);
        initView(context);
    }

    public AutoListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView(context);
    }

    // 下拉刷新监听
    public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
        this.onRefreshListener = onRefreshListener;
    }

    // 加载更多监听
    public void setOnLoadListener(OnLoadListener onLoadListener) {
        this.loadEnable = true;
        this.onLoadListener = onLoadListener;
    }

    public boolean isLoadEnable() {
        return loadEnable;
    }

    //不支持动态调整
    public void setLoadEnable(boolean loadEnable) {
        this.loadEnable = loadEnable;
        this.removeFooterView(footer);
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    // 初始化组件
    private void initView(Context context) {
        inflater = LayoutInflater.from(context);
        footer = inflater.inflate(R.layout.autolistview_footer, null);
        footerProgress = (ImageView) footer.findViewById(R.id.progress);
        loadFull = (TextView) footer.findViewById(R.id.loadFull);
        more = (TextView) footer.findViewById(R.id.more);
        progressAnim = (AnimationDrawable) footerProgress.getBackground();

        header = inflater.inflate(R.layout.pull_to_refresh_header, null);
        header.setClickable(false);
        setHeaderInfo();
        this.addHeaderView(header);
        this.addFooterView(footer);
        this.setOnScrollListener(this);
    }

    public void addOtherHeader(View view) {
        this.addHeaderView(view);
        mExtraHeaderCount++;
    }

    public void addKeepScreenHeader(View view) {
        mKeepScreenHeaderView = view;
    }

    private void setHeaderInfo() {
        tip = (TextView) header.findViewById(R.id.tip);
        lastUpdate = (TextView) header.findViewById(R.id.lastUpdate);
        refreshing = (ImageView) header.findViewById(R.id.refreshing);
        refreshingAnim = (AnimationDrawable) refreshing.getBackground();
        headerContentInitialHeight = header.getPaddingTop();
        measureView(header);
        headerContentHeight = header.getMeasuredHeight();
        topPadding(-headerContentHeight);
    }

    public void doRefresh() {
        if (onRefreshListener != null) {
            state = REFRESHING;
            refreshHeaderViewByState();
            onRefreshListener.onRefresh();
        }
    }

    public void onRefresh() {
        if (onRefreshListener != null) {
            onRefreshListener.onRefresh();
        }
    }

    public void onLoad() {
        if (onLoadListener != null) {
            onLoadListener.onLoad();
        }
    }

    public void onRefreshComplete(String updateTime) {
        lastUpdate.setText(AppUtils.getCurrentTime());
        state = NONE;
        refreshHeaderViewByState();
    }

    public void onRefreshComplete() {
        String currentTime = AppUtils.getCurrentTime();
        onRefreshComplete(currentTime);
    }

    public void onLoadComplete() {
        isLoading = false;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
        if (mKeepScreenHeaderView != null) {
            if (firstVisibleItem >= mExtraHeaderCount) {
                mKeepScreenHeaderView.setVisibility(View.VISIBLE);
            } else {
                mKeepScreenHeaderView.setVisibility(View.GONE);
            }
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
        ifNeedLoad(view, scrollState);
    }

    // 根据listview滑动的状态判断是否需要加载更多
    private void ifNeedLoad(AbsListView view, int scrollState) {
        if (!loadEnable) {
            return;
        }
        try {
            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && !isLoading
                    && view.getLastVisiblePosition() == view.getPositionForView(footer) && !isLoadFull) {
                onLoad();
                isLoading = true;
            }
        } catch (Exception e) {
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (firstVisibleItem == 0) {
                    isRecorded = true;
                    startY = (int) ev.getY();
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (state == PULL) {
                    state = NONE;
                    refreshHeaderViewByState();
                } else if (state == RELEASE) {
                    state = REFRESHING;
                    refreshHeaderViewByState();
                    onRefresh();
                }
                isRecorded = false;
                break;
            case MotionEvent.ACTION_MOVE:
                whenMove(ev);
                break;
        }
        return super.onTouchEvent(ev);
    }

    // 解读手势，刷新header状态
    private void whenMove(MotionEvent ev) {
        if (!isRecorded) {
            return;
        }
        int tmpY = (int) ev.getY();
        int space = tmpY - startY;
        int topPadding = space - headerContentHeight;
        switch (state) {
            case NONE:
                if (space > 0) {
                    state = PULL;
                    refreshHeaderViewByState();
                }
                break;
            case PULL:
                topPadding(topPadding);
                if (scrollState == SCROLL_STATE_TOUCH_SCROLL && space > headerContentHeight + SPACE) {
                    state = RELEASE;
                    refreshHeaderViewByState();
                }
                break;
            case RELEASE:
                topPadding(topPadding);
                if (space > 0 && space < headerContentHeight + SPACE) {
                    state = PULL;
                    refreshHeaderViewByState();
                } else if (space <= 0) {
                    state = NONE;
                    refreshHeaderViewByState();
                }
                break;
        }
    }

    // 调整header的大小。其实调整的只是距离顶部的高度。
    private void topPadding(int topPadding) {
        if (topPadding > 600) {
            return;
        }
        int realPadding = topPadding;
        if (topPadding > 0) {
            realPadding = topPadding / 4;
        }
        header.setPadding(header.getPaddingLeft(), realPadding, header.getPaddingRight(), header.getPaddingBottom());
        header.invalidate();
    }

    public void setResultSize(int resultSize) {
        if (resultSize == 0) {
            isLoadFull = true;
            loadFull.setVisibility(View.GONE);
            progressAnim.stop();
            footerProgress.setVisibility(View.GONE);
            more.setVisibility(View.GONE);
        } else if (resultSize > 0 && resultSize < pageSize) {
            isLoadFull = true;
            loadFull.setVisibility(View.VISIBLE);
            progressAnim.stop();
            footerProgress.setVisibility(View.GONE);
            more.setVisibility(View.GONE);
        } else if (resultSize == pageSize) {
            isLoadFull = false;
            loadFull.setVisibility(View.GONE);
            footerProgress.setVisibility(View.VISIBLE);
            more.setVisibility(View.VISIBLE);
            progressAnim.start();
        }
    }

    // 根据当前状态，调整header
    private void refreshHeaderViewByState() {
        switch (state) {
            case NONE:
                topPadding(-headerContentHeight);
                tip.setText("下拉刷新");
                refreshingAnim.stop();
                break;
            case PULL:
                tip.setText("下拉刷新");
                refreshingAnim.stop();
                break;
            case RELEASE:
                tip.setText("松开刷新");
                refreshingAnim.stop();
                break;
            case REFRESHING:
                topPadding(headerContentInitialHeight);
                tip.setText("正在刷新");
                refreshingAnim.start();
                break;
        }
    }

    private void measureView(View child) {
        ViewGroup.LayoutParams layoutParam = child.getLayoutParams();
        if (layoutParam == null) {
            layoutParam = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, layoutParam.width);
        int lpHeight = layoutParam.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    /*
     * 定义下拉刷新接口
     */
    public interface OnRefreshListener {
        public void onRefresh();
    }

    /*
     * 定义加载更多接口
     */
    public interface OnLoadListener {
        public void onLoad();
    }
}
